﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SecsEquip;
using System.ComponentModel;
using System.Threading;
using SecsEquip300;
using EquipSecs300;
using System.Drawing;
using EquipSecs300.Parameter;
using System.Diagnostics;

namespace EquipSecs300
{
    public class SecsEquipHelper : SecsEquipEx
    {
        public GEM_Alarm Alarm { get; set; }
        public GEM_Even Even { get; set; }
        public GEM_Variables Variables { get; set; }
        public GEM_RemoteContro RemoteContro { get; set; }
        public GEM_Recipe Recipe { get; set; }
        public GEM_PPFormat PPFormat { get; set; }
        public GEM_Constant Constant { get; set; }
        public GEM_PPCostomizeHandleExample PPCostomize { get; set; }
        public GEM_CJob CJob { get; set; }
        public GEM_PJob PJob { get; set; }
        public GEM_LoadPort LoadPort { get; set; }
        public GEM_SubstrateTracking SubstrateTracking { get; set; }


        public Action<object, CommStateEventArgs> onCommStateEventHandler = null;
        public Action<object, ControlStateEventArgs> onControlStateEventHandler = null;
        public Func<object, TerminalEventArgs, TERMINAL_REPLY> onTerminalEventHandler = null;

        private static bool _isSecsEnable;
        public static bool IsSecsEnable{get { return _isSecsEnable; }}

        private static bool _isCreateSelf;
        public static bool IsCreateSelf { get { return _isCreateSelf; } }


        private SecsEquipHelper()
        {
            SecsParameterHelper.InitalSetting();
            SecsDataHelper.InitalSetting();

            m_pSecs = CSecsEquipInstance.GetSecsInstance(IsCreateSelf);
            UpdataData();
        }

        private static readonly object _instanceLock = new object();
        private static SecsEquipHelper _secsHelper;
        public static SecsEquipHelper GetInstance(bool isSecsEnable = true,bool isCreateSelf = false)
        {
            lock (_instanceLock)
            {
                if (_secsHelper == null)
                {
                    _isSecsEnable = isSecsEnable;
                    _isCreateSelf = isCreateSelf;
                    _secsHelper = new SecsEquipHelper();
                }
                return _secsHelper;
            }
        }

        void UpdataData()
        {
            // SECS
            InitSecs();
            InitEvent();

            InitSub();
            UpdataDataSub();
        }

        // SECS
        void InitSecs()
        {
            CSecsEquip300 pSecs = m_pSecs;
            pSecs.SecsEnable(_isSecsEnable);
            RcResult rc = pSecs.start();

            if (SecsDataHelper.Function.Gem300Enable)
            {
                // 初始化 GEM300
                InitSecsGem300(m_pSecs);
            }

            m_pSecs.LoadDataByCsvFile();   // 加载SECS的配置参数 VID,Event,Report,Alarm
            SetSecsParament(SecsParameterHelper.SecsParam);
            if (rc != 0)
            {
                Console.WriteLine("开始连接：错误" + rc.ToString());
            }
        }

        // GEM300初始化
        void InitSecsGem300(CSecsEquip300 pSecs)
        {
            // 初始化E40
            RcResult rc = pSecs.PJobInit();
            if (rc != 0)
            {
                MessageBox.Show(rc.toString());
            }

            // 初始化E87，设备有个Load Port
            InitE87(pSecs);


            // 初始化E90
            rc = pSecs.SubstInit();
            if (rc != 0)
            {
                MessageBox.Show(rc.toString());
            }

            // 初始化E94
            rc = pSecs.CJobInit();
            if (rc != 0)
            {
                MessageBox.Show(rc.toString());
            }
        }

        void InitE87(CSecsEquip300 pSecs)
        {
            RcResult rc = pSecs.CmsInit(4);
            if (rc != 0)
            {
                MessageBox.Show(rc.toString());
            }
            // 初始化Load Port数据
            LoadPort loadPort = new LoadPort();
            loadPort.nAccessMode = LoadPortAccessMode.AUTO;

            loadPort.nPortID = 1;
            pSecs.CmsLoadPortCreate(loadPort);

            loadPort.nPortID = 2;
            pSecs.CmsLoadPortCreate(loadPort);

            loadPort.nPortID = 3;
            pSecs.CmsLoadPortCreate(loadPort);

            loadPort.nPortID = 4;
            pSecs.CmsLoadPortCreate(loadPort);
        }

        void InitSub()
        {
            Alarm = new GEM_Alarm(m_pSecs, this);
            Even = new GEM_Even(m_pSecs, this);
            Variables = new GEM_Variables(m_pSecs, this);
            RemoteContro = new GEM_RemoteContro(m_pSecs, this);
            Recipe = new GEM_Recipe(m_pSecs, this);
            PPFormat = new GEM_PPFormat_All(m_pSecs, this);
            CJob = new GEM_CJob(m_pSecs, this);
            PJob = new GEM_PJob(m_pSecs, this);
            LoadPort = new GEM_LoadPort(m_pSecs, this);
            SubstrateTracking = new GEM_SubstrateTracking(m_pSecs, this);
            Constant = new GEM_Constant(m_pSecs, this);
            PPCostomize = new GEM_PPCostomizeHandleExample(m_pSecs, this);
        }
        void UpdataDataSub()
        {
            Alarm.UpdateData();
            Even.UpdateData();
            Variables.UpdateData();
            RemoteContro.UpdateData();
            Recipe.UpdateData();
            PPFormat.UpdateData();
            CJob.UpdateData();
            PJob.UpdateData();
            LoadPort.UpdateData();
            SubstrateTracking.UpdateData();
            Constant.UpdateData();
            PPCostomize.UpdateData();
        }
        void InitEvent()
        {
            // 回调、委托
            m_pSecs.m_pOnCommState += OnCommStateEventHandler;
            m_pSecs.m_pOnControlState += OnControlStateEventHandler;
            m_pSecs.m_pOnClock += OnClockEventHandler;
            //m_pSecs.m_pOnTerminal += OnTerminalEventHandler;
        }
        public void SetSecsParament(SecsParameter secsParament)
        {
            m_pSecs.SetIP(secsParament.Ip);      //  被动模式建议IP地址设为0.0.0.0
            m_pSecs.SetPort(secsParament.Port);
            m_pSecs.SetPassive(secsParament.Passive);
            m_pSecs.SetDeviceID(secsParament.DeviceID);
            m_pSecs.SetEnableLog(secsParament.EnableLog); // 启用SECS运行LOG

            m_pSecs.SetT1(secsParament.T1);
            m_pSecs.SetT2(secsParament.T2);
            m_pSecs.SetT3(secsParament.T3);
            m_pSecs.SetT4(secsParament.T4);
            m_pSecs.SetT5(secsParament.T5);
            m_pSecs.SetT6(secsParament.T6);
            m_pSecs.SetT7(secsParament.T7);

            // 设置recipe的路径    
            m_pSecs.SetRecipeDirectory(secsParament.ProcessProgramPath);
            m_pSecs.SetWinrarPath(secsParament.WinrarPath);
            m_pSecs.PPAllowHostDowmload(secsParament.PPAllowHostDowmload);
            m_pSecs.PPIsFolderDir(secsParament.PPIsFolder);

            m_pSecs.SetMDLN(secsParament.InterfaceName);
            m_pSecs.SetSOFTREV(secsParament.Softrev);

            m_pSecs.AlarmNotifyEventMode(ALARM_NOTIFY_EVENT_MODE.AlarmUnifyEvent);//设置报警发生后的通知模式
            m_pSecs.ConstantChangeSendEventEnable(false);

            // 设置设备软件初始化后的SECS/GEM控制状态，建议放到配置参数里面
            m_pSecs.SetControlMode(secsParament.ControlMode);

            if (secsParament.CommEnable)
            {
                m_pSecs.CommEnable();
            }
            else
            {
                m_pSecs.CommDisable();
            }

        }

        [Description("控制状态改变")]
        void OnCommStateEventHandler(object sender, CommStateEventArgs e)
        {
            LogMsg($"**********控制状态改变 -> {e.nState.ToString()}***********");
            // 把显示处理给到界面线程
            onCommStateEventHandler?.Invoke(sender, e);
        }
        [Description("通讯状态改变")]
        void OnControlStateEventHandler(object sender, ControlStateEventArgs e)
        {
            // 把显示处理给到界面线程
            onControlStateEventHandler?.Invoke(sender, e);
            switch (e.nState)
            {
                case CONTROL_STATE.eCONTROL_ONLINE_REMOTE:
                    {
                        GlobalVar.EAPRemote = true;
                        //Even.Ev_EAP_STATE(EAPConnectionStatus_KE.OnLine);
                    }
                    break;
                case CONTROL_STATE.eCONTROL_ONLINE_LOCAL:
                    {
                        GlobalVar.EAPRemote = false;
                        //Even.Ev_EAP_STATE(EAPConnectionStatus_KE.Local);
                    }
                    break;
                default:
                    {
                        GlobalVar.EAPRemote = false;
                        //Even.Ev_EAP_STATE(EAPConnectionStatus_KE.Offline);
                    }
                    break;
            }
            LogMsg($"**********通讯状态改变 -> {e.nState}***********");
        }
        [Description("终端消息")]
        TERMINAL_REPLY OnTerminalEventHandler(object sender, TerminalEventArgs e)
        {
            if (onTerminalEventHandler == null)
            {
                return TERMINAL_REPLY.eMESSAGE_WILL_NOT_BE_DISPLAY;
            }
            // 把显示处理给到界面线程
            return onTerminalEventHandler.Invoke(sender, e);
        }
        void OnClockEventHandler(object sender, ClockEventArgs e)
        {
            SysTimeHelper sysTime = new SysTimeHelper();
            sysTime.SetSysTime(e.time);
            LogMsg($"收到EAP时间: {e.time.ToString()}", MsgSource_KE.EAP);
        }

        public void Quit()
        {
            m_pSecs.CommDisable();
            m_pSecs.Abort();
        }

    }


}
